package com.example.spring.multi.module.logic.controller.other;

import com.example.spring.multi.module.minio.MinIoUtil;
import io.minio.MinioClient;
import io.minio.errors.MinioException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @program: knowledge-pooling
 * @ClassName MinioController
 * @description:
 * @author: tomato
 * @create: 2023-07-24 09:58
 * @Version 1.0
 **/

@RestController
@RequestMapping("/test")
@Slf4j
public class MinioController {
    private static final String MINIO_ENDPOINT = "http://192.168.50.206:9000/";
    private static final String MINIO_ACCESS_KEY = "admin";
    private static final String MINIO_SECRET_KEY = "password";
    private static final String BUCKET_NAME = "epms";
    private static final String FILE_NAME = "111.txt";
    private final MinIoUtil minIoUtil;

    public MinioController(MinIoUtil minIoUtil) {
        this.minIoUtil = minIoUtil;
    }

    @GetMapping("/download")
    //远程Minio 流式返回 流式响应
    public void test(HttpServletResponse response) {
        try {
            long l = System.currentTimeMillis();
            log.info("开始下载文件" + l);
            InputStream epms = minIoUtil.getObject("epms", "/cappData/json/2023/07/20/111.txt");
            log.info("下载文件结束" + (System.currentTimeMillis() - l));
            String content = readFile(epms);
            // 设置响应内容类型为文本
            response.setContentType("text/plain");
            // 将文件内容写入响应输出流
            response.getWriter().write(content);
            log.info("耗时：{}", System.currentTimeMillis() - l);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @GetMapping("/download2")
    //本地Minio 流式返回 流式响应
    protected void doGet(HttpServletResponse response) throws ServletException, IOException, NoSuchAlgorithmException, InvalidKeyException {
        try {
            // 创建MinIO客户端
            MinioClient minioClient = new MinioClient(MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY);

            long l = System.currentTimeMillis();
            log.info("开始下载文件" + l);
            // 下载文件
            InputStream inputStream = minioClient.getObject(BUCKET_NAME, FILE_NAME);
            log.info("下载文件结束" + (System.currentTimeMillis() - l));

            // 设置响应内容类型
            response.setContentType("application/octet-stream");
            // 设置响应头，使浏览器下载文件
            response.setHeader("Content-Disposition", "attachment; filename=\"" + FILE_NAME + "\"");

            // 获取响应输出流
            OutputStream outputStream = response.getOutputStream();

            // 将文件内容写入输出流
            byte[] buffer = new byte[40960];
            int bytesRead;
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }

            // 关闭输入流和输出流
            inputStream.close();
            outputStream.close();
            log.info("耗时：{}", System.currentTimeMillis() - l);
        } catch (MinioException e) {
            e.printStackTrace();
        }
    }

    // 读取txt文件内容
    private String readFile(InputStream file) throws IOException {
        StringBuilder content = new StringBuilder();

        try (BufferedReader reader = new BufferedReader(new InputStreamReader(file))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line);
                content.append("\n");
            }
        }
        return content.toString();
    }

    @GetMapping("/download3")
    //本地Minio 下载到本地 String返回
    public String download3() {
        try {
            long l = System.currentTimeMillis();
            // Initialize Minio client
            MinioClient minioClient = new MinioClient(MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY);
            // Download file from MinIO server
            minioClient.getObject(BUCKET_NAME, FILE_NAME, FILE_NAME);
            // Read file content into a string
            String fileContent = readFileToString();
            // TODO: Return the file content to the client or perform further processing
            log.info("下载文件结束" + (System.currentTimeMillis() - l));
            removeDownloadedFile();
            log.info("耗时：{}", System.currentTimeMillis() - l);
            return fileContent;
        } catch (MinioException e) {
            System.out.println("Error occurred: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private static String readFileToString() throws IOException {
        StringBuilder content = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                new FileInputStream(MinioController.FILE_NAME), StandardCharsets.UTF_8));
        String line;
        while ((line = reader.readLine()) != null) {
            content.append(line);
            content.append(System.lineSeparator());
        }
        reader.close();
        return content.toString();
    }

    private static void removeDownloadedFile() {
        File file = new File(MinioController.FILE_NAME);
        if (file.exists()) {
            file.delete();
        }
    }

    @GetMapping("/download4")
    //本地Minio 流式获取 String返回
    public String download4() {





        //测试
        try {
            long l = System.currentTimeMillis();
            // Initialize Minio client
            MinioClient minioClient = new MinioClient(MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY);

            // Get the file content as InputStream from MinIO server
            InputStream inputStream = minioClient.getObject(BUCKET_NAME, FILE_NAME);

            // Read the InputStream into a string
            String fileContent = readInputStreamToString(inputStream);
            inputStream.close();
            log.info("下载文件结束" + (System.currentTimeMillis() - l));
            return fileContent;
        } catch (MinioException e) {
            System.out.println("Error occurred: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    private static String readInputStreamToString(InputStream inputStream) throws Exception {
        StringBuilder content = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8));

        String line;
        while ((line = reader.readLine()) != null) {
            content.append(line);
            content.append(System.lineSeparator());
        }

        reader.close();
        return content.toString();
    }

    @GetMapping("/download5")
    //本地Minio 流式获取 流式响应
    protected void download5(HttpServletResponse response) throws ServletException, IOException, NoSuchAlgorithmException, InvalidKeyException {
        try {
            // 创建MinIO客户端
            MinioClient minioClient = new MinioClient(MINIO_ENDPOINT, MINIO_ACCESS_KEY, MINIO_SECRET_KEY);

            long l = System.currentTimeMillis();
            log.info("开始下载文件" + l);
            // 下载文件
            InputStream inputStream = minioClient.getObject(BUCKET_NAME, FILE_NAME);
            log.info("下载文件结束" + (System.currentTimeMillis() - l));

            // 设置响应内容类型
            response.setContentType("application/octet-stream");
            // 设置响应头，使浏览器下载文件
            response.setHeader("Content-Disposition", "attachment; filename=\"" + FILE_NAME + "\"");

            // 获取响应输出流
            OutputStream outputStream = response.getOutputStream();

            // 将文件内容写入输出流
            try {
                byte[] b = new byte[1024];
                int length;
                while ((length = inputStream.read(b)) > 0) {
                    outputStream.write(b, 0, length);
                }
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    }
                }
            }
            log.info("耗时：{}", System.currentTimeMillis() - l);
        } catch (MinioException e) {
            e.printStackTrace();
        }
    }

}
